package com.ccys.common.util.easyExcel;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.SimpleColumnWidthStyleStrategy;
import org.apache.poi.ss.formula.functions.T;
import org.apache.poi.ss.usermodel.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.LinkedList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * EasyExcel工具类
 */
public class EasyExcelUtil {

    /**
     * 导出excel
     */
    public static void export(HttpServletResponse response, List<?> list,Class clazz,String fileName){
        try {
            // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            fileName = URLEncoder.encode(fileName, "UTF-8");
            response.setHeader("Content-disposition", "attachment;filename=" + fileName);
            //response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), clazz).registerWriteHandler(new CustomWeightStrategy()).sheet("sheet1").doWrite(list);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    /**
     * 设置响应信息
     */
    public static void setResponse(HttpServletResponse response,String fileName){
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        response.setHeader("Content-disposition", "attachment;filename=" + fileName + ".xlsx");
    }

    /**
     * 自定义导出
     */
    public static void export(HttpServletResponse response,List<List<Object>> data,List<String> head,String fileName) throws IOException {
        setResponse(response,fileName);
        // 标题样式
        WriteCellStyle headWriteCellStyle = getHeadStyle();
        // 这个策略是 头是头的样式 内容是内容的样式 其他的策略可以自己实现
        HorizontalCellStyleStrategy horizontalCellStyleStrategy =
                new HorizontalCellStyleStrategy(headWriteCellStyle, new WriteCellStyle());
        EasyExcel.write(response.getOutputStream())
                // 第一行大标题样式设置
//                .registerWriteHandler(new SheetWriteHandlerUtil(fileName))
                //设置默认样式及写入头信息开始的行数
                .useDefaultStyle(true).relativeHeadRowIndex(1)
                // 表头、内容样式设置
                .registerWriteHandler(horizontalCellStyleStrategy)
                // 统一列宽,如需设置自动列宽则new CustomWeightStrategy()
                .registerWriteHandler(new SimpleColumnWidthStyleStrategy(25))
                .sheet(fileName)
                // 这里放入动态头
                .head(head(head,fileName))
                // 当然这里数据也可以用 List<List<String>> 去传入
                .doWrite(data);
    }

    /**动态头传入*/
    public static List<List<String>> head(List<String> header, String bigTitle) {
        List<String> head0 = null;
        List<List<String>> list = new LinkedList<List<String>>();
        for (String h : header) {
            head0 = new LinkedList<>();
            head0.add(bigTitle);
            head0.add(h);
            list.add(head0);
        }
        return list;
    }

    public static WriteCellStyle getHeadStyle(){
        // 头的策略
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        // 背景颜色
        headWriteCellStyle.setFillForegroundColor(IndexedColors.WHITE.getIndex());
        headWriteCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        // 字体
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontName("黑体");//设置字体名字
        headWriteFont.setFontHeightInPoints((short)15);//设置字体大小
        headWriteFont.setBold(true);//字体加粗
        headWriteCellStyle.setWriteFont(headWriteFont); //在样式用应用设置的字体;
        // 样式
        headWriteCellStyle.setBorderBottom(BorderStyle.THIN);//设置底边框;
        headWriteCellStyle.setBottomBorderColor((short) 0);//设置底边框颜色;
        headWriteCellStyle.setBorderLeft(BorderStyle.THIN);  //设置左边框;
        headWriteCellStyle.setLeftBorderColor((short) 0);//设置左边框颜色;
        headWriteCellStyle.setBorderRight(BorderStyle.THIN);//设置右边框;
        headWriteCellStyle.setRightBorderColor((short) 0);//设置右边框颜色;
        headWriteCellStyle.setBorderTop(BorderStyle.THIN);//设置顶边框;
        headWriteCellStyle.setTopBorderColor((short) 0); //设置顶边框颜色;
        headWriteCellStyle.setWrapped(true);  //设置自动换行;
        headWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);//设置水平对齐的样式为居中对齐;
        headWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);  //设置垂直对齐的样式为居中对齐;
        //        headWriteCellStyle.setShrinkToFit(true);//设置文本收缩至合适

        return headWriteCellStyle;
    }

    /**
     * 读取Excel文件，并将数据导入到Java对象中
     * @param file Excel文件
     * @param clazz Java对象的类型
     * @return 包含数据的List对象
     * @throws IOException IO异常
     */
    public static <T> List<T> readExcelCSV(MultipartFile file, Class<T> clazz) {

        //excel读取数据
        List<T> excelList = null;
        try {
            excelList = EasyExcel.read(new BufferedInputStream(file.getInputStream()), clazz,null).excelType(ExcelTypeEnum.CSV).sheet().doReadSync();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if(excelList == null) {
            return null;
        }
        //stream流去重
        return excelList.stream().distinct().collect(Collectors.toList());
    }


}
